package com.fb;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Date;

/**
 * @author sad
 */
public class IpCameraVideoGrabber {

    private Thread thread;
    private File file;
    private boolean capturing = false;
    private volatile boolean shouldBreak = false;
    private final FacebookSender fbSender;
    private OnEndEvent endEvent;
    private boolean externalBreak = false;
    private String userEmail;

    public abstract static class OnEndEvent {

        public void videoUploaded(String facebookUrl, String userEmail) {
        }

        public void onError(String message) {
        }

        public void timeout() {
        }

        public void fileDownloaded(File uploadedMjpeg) {
        }

        public void fileConverted(File convertedFile) {
        }

        public void end() {
        }
    }

    public IpCameraVideoGrabber(FacebookSender sender, OnEndEvent event) {
        fbSender = sender;
        if (sender == null) {
            throw new IllegalArgumentException("sender cannot be null");
        }
        endEvent = event;
    }

    public static void main(String[] a) {
        Thread thread = new Thread() {
            @Override
            public void run() {
                int i = 0;
                while (true) {
                    System.out.println(i++);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        thread.start();
    }

    public void startWriting(final String url, final String user, final String password, final File directory, final int frameRate) {
        if (capturing == true) {
            return;
        }

        thread = new Thread() {
            @Override
            public void run() {
                try {
                    try {
                        file = new File(directory, System.currentTimeMillis() + ".avi");
                        System.out.println("File " + file.getAbsolutePath());
                        String command = ".\\ffmpeg\\ffmpeg.exe -f rtsp -i \"" + url + "\" -vcodec mpeg4 \"" + file.getAbsolutePath() + "\"";
                        System.out.println("Started grabbing1");
                        Process process = Runtime.getRuntime().exec(command);

                        System.out.println("Started grabbing2");
                        OutputStream outputStream = process.getOutputStream();
                        System.out.println("Started grabbing3");


                        long time = System.currentTimeMillis();
                        while (true) {
                            long t = System.currentTimeMillis();
                            if (shouldBreak || externalBreak ) {
                                System.out.println("Stop recieved externalBreak = " + externalBreak);
                                System.out.println("Stop recieved shouldBreak = " + shouldBreak);

                                OutputStream ostream = process.getOutputStream(); //Get the output stream of the process, which translates to what would be user input for the commandline
                                ostream.write("q".getBytes());       //write out the character Q, followed by a newline or carriage return so it registers that Q has been 'typed' and 'entered'.
                                //ostream.flush();
                    /*                 char ctrlBreak =  'q';
                                    outputStream.write(ctrlBreak);
                    */
                                try {
                                    System.out.println("Stop recieved2");

                                    outputStream.flush();

                                    System.out.println("Stop recieved2");
                                } catch (Exception ex) {
                                }
                                BufferedReader is = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                                String line;
                                while ((line = is.readLine()) != null) {
                                    System.out.println("ffmpeg  error: " + line);
                                }
/*
                                BufferedReader is2 = new BufferedReader(new InputStreamReader(process.getInputStream()));
                                String line2;
                                while ((line2 = is2.readLine()) != null) {
                                    System.out.println("ffmpeg  input: " + line2);
                                }
*/

                                process.waitFor();
                                endEvent.fileConverted(file);
                                System.out.println("Stop recieved5");
                                break;
                            }

                            //  System.out.println("Sleeping");
                            //Thread.sleep(200);
                        }
                        System.out.println("Stop recieved7");
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        printError("Error!! Error while uploading to facebook.");
                        return;
                    }

                    System.out.println("File downloaded " + new Date());
                    endEvent.fileDownloaded(file);
                    try {
                        if (userEmail != null && !userEmail.isEmpty()) {
                            String uploadedVideoUrl = uploadToFacebook(file, userEmail);
                            if (uploadedVideoUrl == null) {
                                printError("Error!! Error while uploading to facebook.");
                                return;
                            }
                            System.out.println("Facebook url = " + uploadedVideoUrl);
                            endEvent.videoUploaded(uploadedVideoUrl, userEmail);
                        }

                        //  file.delete();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                        printError("Error!!! " + ex.getMessage());

                    }
                } finally {
                    capturing = true;
                    endEvent.end();
                }
            }
        };

        thread.start();
    }

    private void printError(String message) {
        System.err.println(message);
        endEvent.onError(message);
    }

    public void endGrabbing(String userEmail) {
        shouldBreak = true;
        this.userEmail = userEmail;
    }

    public void forceEnd() {
        externalBreak = true;
    }

    private String uploadToFacebook(File file, String userEmail) {
        try {
            return fbSender.startVideoFileUploading(file, userEmail);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }
}
